home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / x / volume2 / x11.3 / patch5 < prev    next >
Encoding:
Internet Message Format  |  1989-01-09  |  49.5 KB

  1. Path: uunet!wyse!mikew
  2. From: mikew@wyse.wyse.com (Mike Wexler)
  3. Newsgroups: comp.sources.x
  4. Subject: v02i081:  X11 Release 3, Patch5
  5. Message-ID: <1976@wyse.wyse.com>
  6. Date: 10 Jan 89 01:41:19 GMT
  7. Organization: Wyse Technology, San Jose
  8. Lines: 1784
  9. Approved: mikew@wyse.com
  10.  
  11. Submitted-by: jim@expo.lcs.mit.edu (Jim Fulton)
  12. Posting-number: Volume 2, Issue 81
  13. Archive-name: x11.3/patch5
  14.  
  15.  
  16.  
  17.                Created on Monday, 9 January 1989
  18.  
  19.                   PART 1 of 3
  20.  
  21.  
  22. Fixes 5, 6, and 7 are part of a single update to the xman program.  Together
  23. they affect the following files:
  24.  
  25.     clients/xman/CHANGES
  26.     clients/xman/README
  27.     clients/xman/ScrollByL.c
  28.     clients/xman/TODO
  29.     clients/xman/buttons.c
  30.     clients/xman/defs.h
  31.     clients/xman/globals.c
  32.     clients/xman/globals.h
  33.     clients/xman/handler.c
  34.     clients/xman/help.c
  35.     clients/xman/main.c
  36.     clients/xman/man.c
  37.     clients/xman/man.h
  38.     clients/xman/menu.c
  39.     clients/xman/misc.c
  40.     clients/xman/pages.c
  41.     clients/xman/search.c
  42.     clients/xman/tkfuncs.c
  43.     clients/xman/version.h
  44.     clients/xman/xman.help
  45.     clients/xman/xman.man
  46.  
  47. To apply these fixes, concatenate all three files and pipe them to patch -p0
  48. from the top of your X sources:
  49.  
  50.     %  cat fix5 fix6 fix7 | patch -p0
  51.  
  52.  
  53. The following is fix5 (you will also need fix6 and fix7):
  54.  
  55.  
  56.  
  57. *** /tmp/,RCSt1a17149    Fri Jan  6 18:56:33 1989
  58. --- clients/xman/buttons.c    Fri Jan  6 18:41:55 1989
  59. ***************
  60. *** 1,8 ****
  61.   /*
  62.    * xman - X window system manual page display program.
  63.    *
  64. !  * $XConsortium: buttons.c,v 1.2 88/09/04 20:27:16 swick Exp $
  65. !  * $oHeader: buttons.c,v 4.0 88/08/31 22:11:26 kit Exp $
  66.    *
  67.    * Copyright 1987, 1988 Massachusetts Institute of Technology
  68.    *
  69. --- 1,8 ----
  70.   /*
  71.    * xman - X window system manual page display program.
  72.    *
  73. !  * $XConsortium: buttons.c,v 1.3 89/01/06 18:41:51 kit Exp $
  74. !  * $Header: buttons.c,v 1.3 89/01/06 18:41:51 kit Exp $
  75.    *
  76.    * Copyright 1987, 1988 Massachusetts Institute of Technology
  77.    *
  78. ***************
  79. *** 21,27 ****
  80.    */
  81.   
  82.   #if ( !defined(lint) && !defined(SABER))
  83. !   static char rcs_version[] = "$Athena: buttons.c,v 4.0 88/08/31 22:11:26 kit Exp $";
  84.   #endif
  85.   
  86.   #include "globals.h"
  87. --- 21,27 ----
  88.    */
  89.   
  90.   #if ( !defined(lint) && !defined(SABER))
  91. !   static char rcs_version[] = "$Athena: buttons.c,v 4.5 88/12/19 13:46:34 kit Exp $";
  92.   #endif
  93.   
  94.   #include "globals.h"
  95. ***************
  96. *** 45,53 ****
  97.   #define TOPARGS 5
  98.   
  99.   void
  100. ! MakeTopMenuWidget(top)
  101. ! Widget top;
  102.   {
  103.     Widget menu;            /* Top Box and menu. */
  104.     Menu topbox;            /* The menu structure for this box. */
  105.     Button topbuttons[TOPBUTTONS]; /* The button structure for these buttons. */
  106. --- 45,53 ----
  107.   #define TOPARGS 5
  108.   
  109.   void
  110. ! MakeTopMenuWidget()
  111.   {
  112. +   Widget top;            /* top box widget. */
  113.     Widget menu;            /* Top Box and menu. */
  114.     Menu topbox;            /* The menu structure for this box. */
  115.     Button topbuttons[TOPBUTTONS]; /* The button structure for these buttons. */
  116. ***************
  117. *** 60,65 ****
  118. --- 60,80 ----
  119.       "Manual Page"
  120.       };
  121.   
  122. + /* create the top icon. */
  123. +   num_args = 0;
  124. +   XtSetArg(arglist[num_args], XtNiconPixmap,
  125. +        XCreateBitmapFromData( XtDisplay(initial_widget), 
  126. +                  XtScreen(initial_widget)->root,
  127. +                  iconclosed_bits, iconclosed_width,
  128. +                  iconclosed_height));
  129. +   num_args++;
  130. +   XtSetArg(arglist[num_args], XtNallowShellResize, TRUE); 
  131. +   num_args++;
  132. +   top = XtCreatePopupShell(TOPBOXNAME, topLevelShellWidgetClass, 
  133. +                initial_widget, arglist, num_args);
  134.     /* Set up the manual structure. */
  135.   
  136.     topbox.number = TOPBUTTONS;
  137. ***************
  138. *** 73,79 ****
  139.     topbox.buttons = topbuttons;
  140.     topbox.callback = TopCallback;
  141.   
  142. ! /* Set up the button structures, by assiging each one a name and a 
  143.    * width, this puts either one button on a line or two depending on
  144.    * the length of the string that will go into the buttons. See Menu.c for 
  145.    * details.
  146. --- 88,95 ----
  147.     topbox.buttons = topbuttons;
  148.     topbox.callback = TopCallback;
  149.   
  150. ! /*
  151. !  * Set up the button structures, by assiging each one a name and a 
  152.    * width, this puts either one button on a line or two depending on
  153.    * the length of the string that will go into the buttons. See Menu.c for 
  154.    * details.
  155. ***************
  156. *** 91,105 ****
  157.     menu = MakeMenu(top,&topbox, NULL); /* Create the menu. */
  158.     XtManageChild(menu);        /* Manage the menu. */
  159.   
  160. ! /* create the top icon. */
  161. !   num_args = 0;
  162. !   XtSetArg(arglist[num_args], XtNiconPixmap,
  163. !        XCreateBitmapFromData( XtDisplay(top), XtScreen(top)->root,
  164. !                  iconclosed_bits, iconclosed_width,
  165. !                  iconclosed_height));
  166. !   num_args++;
  167. !   XtSetValues(top,arglist,num_args);
  168.   }
  169.   
  170.   /*    Function Name: CreateManpage
  171. --- 107,115 ----
  172.     menu = MakeMenu(top,&topbox, NULL); /* Create the menu. */
  173.     XtManageChild(menu);        /* Manage the menu. */
  174.   
  175. !   XtRealizeWidget(top);
  176. !   XtMapWidget(top);
  177. !   AddCursor(top, resources.cursors.top);
  178.   }
  179.   
  180.   /*    Function Name: CreateManpage
  181. ***************
  182. *** 136,142 ****
  183.   
  184.   /* Initialize the number of screens that will be shown */
  185.   
  186. !   man_globals->both_shown = both_shown_initial;
  187.   
  188.     for ( i = 0 ; i < sections ; i++) 
  189.       man_globals->manpagewidgets.box[i] = NULL;
  190. --- 146,152 ----
  191.   
  192.   /* Initialize the number of screens that will be shown */
  193.   
  194. !   man_globals->both_shown = resources.both_shown_initial;
  195.   
  196.     for ( i = 0 ; i < sections ; i++) 
  197.       man_globals->manpagewidgets.box[i] = NULL;
  198. ***************
  199. *** 174,181 ****
  200.     XtSetArg(arglist[num_args], XtNheight, default_height);
  201.     num_args++; 
  202.   
  203. !   top = XtCreateApplicationShell(name, topLevelShellWidgetClass,
  204. !                  arglist, num_args);
  205.   
  206.     man_globals->This_Manpage = top; /* pointer to root widget of Manualpage. */
  207.     num_args = 0;
  208. --- 184,191 ----
  209.     XtSetArg(arglist[num_args], XtNheight, default_height);
  210.     num_args++; 
  211.   
  212. !   top = XtCreatePopupShell(name, topLevelShellWidgetClass, initial_widget,
  213. !                arglist, num_args);
  214.   
  215.     man_globals->This_Manpage = top; /* pointer to root widget of Manualpage. */
  216.     num_args = 0;
  217. ***************
  218. *** 215,230 ****
  219.       mpw->directory = XtCreateWidget(DIRECTORY_NAME, viewportWidgetClass,
  220.                       pane, arglist, num_args);
  221.       
  222. !     man_globals->current_directory = 1;
  223.       MakeDirectoryBox(man_globals, mpw->directory,
  224. !              mpw->box + man_globals->current_directory, 1);
  225.       XtManageChild(mpw->box[man_globals->current_directory]);
  226.     }
  227.   
  228.   /* Create Manpage */
  229.   
  230. !   font_height = (fonts.normal->max_bounds.ascent + 
  231. !            fonts.normal->max_bounds.descent);
  232.   
  233.     num_args = 0;
  234.     XtSetArg(arglist[num_args], XtNallowVert, TRUE);
  235. --- 225,241 ----
  236.       mpw->directory = XtCreateWidget(DIRECTORY_NAME, viewportWidgetClass,
  237.                       pane, arglist, num_args);
  238.       
  239. !     man_globals->current_directory = INITIAL_DIR;
  240.       MakeDirectoryBox(man_globals, mpw->directory,
  241. !              mpw->box + man_globals->current_directory, 
  242. !              man_globals->current_directory );
  243.       XtManageChild(mpw->box[man_globals->current_directory]);
  244.     }
  245.   
  246.   /* Create Manpage */
  247.   
  248. !   font_height = (resources.fonts.normal->max_bounds.ascent + 
  249. !            resources.fonts.normal->max_bounds.descent);
  250.   
  251.     num_args = 0;
  252.     XtSetArg(arglist[num_args], XtNallowVert, TRUE);
  253. ***************
  254. *** 285,291 ****
  255.       if (man_globals->both_shown) {
  256.         XtManageChild(dir);
  257.         man_globals->dir_shown = TRUE;
  258. !       XtPanedSetMinMax(dir, directory_height, directory_height);
  259.         XtSetSensitive(man_globals->put_up_manpage,FALSE);
  260.         XtSetSensitive(man_globals->put_up_directory,FALSE);
  261.         ChangeLabel(man_globals->both_shown_button, SHOW_ONE);
  262. --- 296,303 ----
  263.       if (man_globals->both_shown) {
  264.         XtManageChild(dir);
  265.         man_globals->dir_shown = TRUE;
  266. !       XtPanedSetMinMax(dir, resources.directory_height, 
  267. !                resources.directory_height);
  268.         XtSetSensitive(man_globals->put_up_manpage,FALSE);
  269.         XtSetSensitive(man_globals->put_up_directory,FALSE);
  270.         ChangeLabel(man_globals->both_shown_button, SHOW_ONE);
  271. ***************
  272. *** 320,326 ****
  273.    */
  274.   
  275.     XtRealizeWidget(  man_globals->This_Manpage );
  276. !   AddCursor( man_globals->This_Manpage, cursors.manpage);
  277.     XtPanedSetMinMax(dir, 1, 10000); 
  278.   }
  279.   
  280. --- 332,340 ----
  281.    */
  282.   
  283.     XtRealizeWidget(  man_globals->This_Manpage );
  284. !   XtMapWidget( man_globals->This_Manpage );
  285. !   AddCursor( man_globals->This_Manpage, resources.cursors.manpage);
  286.     XtPanedSetMinMax(dir, 1, 10000); 
  287.   }
  288.   
  289. ***************
  290. *** 467,473 ****
  291.     MakeLong((Widget) pupwidget);
  292.   
  293.     XtRealizeWidget(popup_shell);    /* Realize it and change its cursor. */
  294. !   AddCursor(popup_shell,cursors.top);
  295.   }
  296.   
  297.   /*    Function Name: MakeDirPopUpWidget
  298. --- 481,487 ----
  299.     MakeLong((Widget) pupwidget);
  300.   
  301.     XtRealizeWidget(popup_shell);    /* Realize it and change its cursor. */
  302. !   AddCursor(popup_shell,resources.cursors.top);
  303.   }
  304.   
  305.   /*    Function Name: MakeDirPopUpWidget
  306. ***************
  307. *** 494,513 ****
  308.     Arg args[1];            /* The argument list. */
  309.     int i;            /* A counter. */
  310.     Cardinal num_args = 0;    /* The number of arguments. */
  311. -   static char * name[MAXSECT];    /*the names of of the popups */
  312.   
  313. - /* Get the names from the manual structure. */
  314. -   for ( i = 1; i < sections; i++)
  315. -     name[i - 1] = manual[i].blabel;
  316.     popup_shell = XtCreatePopupShell( SPOPUPNAME, overrideShellWidgetClass,
  317.                      widget, NULL, (Cardinal) 0);
  318.     XtSetArg(args[num_args],XtNjustify,XtJustifyLeft); 
  319.     num_args++;
  320.   
  321. !   popup.number = sections - 1;    /* We ignore section (0) even though it is
  322. !                    in the manual structure. */
  323.     popup.name = "Manual Sections";
  324.     popup.label_args = NULL;
  325.     popup.label_num = (Cardinal) 0;
  326. --- 508,520 ----
  327.     Arg args[1];            /* The argument list. */
  328.     int i;            /* A counter. */
  329.     Cardinal num_args = 0;    /* The number of arguments. */
  330.   
  331.     popup_shell = XtCreatePopupShell( SPOPUPNAME, overrideShellWidgetClass,
  332.                      widget, NULL, (Cardinal) 0);
  333.     XtSetArg(args[num_args],XtNjustify,XtJustifyLeft); 
  334.     num_args++;
  335.   
  336. !   popup.number = sections;
  337.     popup.name = "Manual Sections";
  338.     popup.label_args = NULL;
  339.     popup.label_num = (Cardinal) 0;
  340. ***************
  341. *** 518,525 ****
  342.     popup.buttons = buttons;
  343.     popup.callback = DirPopUpCallback;
  344.   
  345. !   for ( i = 0 ; i < sections - 1; i ++) {
  346. !     buttons[i].name = name[i];
  347.       buttons[i].number_per_line = 0;
  348.     }
  349.   
  350. --- 525,532 ----
  351.     popup.buttons = buttons;
  352.     popup.callback = DirPopUpCallback;
  353.   
  354. !   for ( i = 0 ; i < sections; i ++) {
  355. !     buttons[i].name = manual[i].blabel;
  356.       buttons[i].number_per_line = 0;
  357.     }
  358.   
  359. ***************
  360. *** 529,566 ****
  361.     XtManageChild(pupwidget);
  362.     (void) MakeLong(pupwidget);
  363.     XtRealizeWidget(popup_shell);
  364. !   AddCursor(popup_shell,cursors.top);
  365.   }
  366.   
  367.   /*    Function Name: CreateManpageName
  368.    *    Description: Creates the manual page name for a given item.
  369. !  *    Arguments: filename - the filename to convert.
  370.    *    Returns: the manual page properly allocated.
  371.    */
  372.   
  373.   /*
  374. !  * If the filename is foo.c - Create an entry of the form:  foo
  375. !  * If the filename is foo.cX - Create an entry of the form: foo(X)
  376.    */
  377.   
  378.   char *
  379. ! CreateManpageName(filename)
  380. ! char * filename;
  381.   {
  382. !   char * cp, temp[BUFSIZ];
  383.   
  384. !   strcpy(temp, filename);
  385. !   cp = rindex(temp, '.');
  386. !   if (cp[2] != '\0') {
  387. !     *cp++ = '(';  
  388. !     *cp++ = *(cp + 1);
  389.       *cp++ = ')';
  390.       *cp = '\0';
  391.     }
  392.     else
  393.       *cp = '\0';  
  394. !   
  395. !   return(StrAlloc(temp));
  396.   }
  397.   
  398.   /*    Function Name: CreateList
  399. --- 536,578 ----
  400.     XtManageChild(pupwidget);
  401.     (void) MakeLong(pupwidget);
  402.     XtRealizeWidget(popup_shell);
  403. !   AddCursor(popup_shell,resources.cursors.top);
  404.   }
  405.   
  406.   /*    Function Name: CreateManpageName
  407.    *    Description: Creates the manual page name for a given item.
  408. !  *    Arguments: entry - the entry to convert.
  409.    *    Returns: the manual page properly allocated.
  410.    */
  411.   
  412.   /*
  413. !  * If the filename is foo.3     - Create an entry of the form:  foo
  414. !  * If the filename is foo.3X11 
  415. !  * or foo.cX11.stuff            - Create an entry of the form:  foo(X11)
  416.    */
  417.   
  418.   char *
  419. ! CreateManpageName(entry)
  420. ! char * entry;
  421.   {
  422. !   char * cp;
  423. !   char page[BUFSIZ];
  424.   
  425. !   ParseEntry(entry, NULL, NULL, page);
  426. !   cp = index(page, '.');
  427. !   if ( (cp[2] != '\0') && (cp[2] != '.') ) {
  428. !     *cp++ = '(';
  429. !     while( (cp[1] != '\0') && (cp[1] != '.') ) {
  430. !       *cp = cp[1]; cp++;
  431. !     }
  432.       *cp++ = ')';
  433.       *cp = '\0';
  434.     }
  435.     else
  436.       *cp = '\0';  
  437. !   return(StrAlloc(page));
  438.   }
  439.   
  440.   /*    Function Name: CreateList
  441. ***************
  442. *** 581,587 ****
  443.   
  444.     for (current = ret_list, count = 0 ; count < manual[section].nentries ;
  445.          count++, current++)
  446. !     *current = CreateManpageName(manual[section].entries[count].label);
  447.    
  448.     *current = NULL;        /* NULL terminate the list. */
  449.     return(ret_list);
  450. --- 593,599 ----
  451.   
  452.     for (current = ret_list, count = 0 ; count < manual[section].nentries ;
  453.          count++, current++)
  454. !     *current = CreateManpageName(manual[section].entries[count]);
  455.    
  456.     *current = NULL;        /* NULL terminate the list. */
  457.     return(ret_list);
  458. ***************
  459. *** 618,624 ****
  460.     num_args++;
  461.     XtSetArg(arglist[num_args], XtNborderWidth, 0);
  462.     num_args++;
  463. !   XtSetArg(arglist[num_args], XtNfont, fonts.directory);
  464.     num_args++;
  465.     
  466.     *dir_disp = XtCreateWidget(DIRECTORY_NAME, listWidgetClass, parent,
  467. --- 630,636 ----
  468.     num_args++;
  469.     XtSetArg(arglist[num_args], XtNborderWidth, 0);
  470.     num_args++;
  471. !   XtSetArg(arglist[num_args], XtNfont, resources.fonts.directory);
  472.     num_args++;
  473.     
  474.     *dir_disp = XtCreateWidget(DIRECTORY_NAME, listWidgetClass, parent,
  475. ***************
  476. *** 669,675 ****
  477.                           arglist,num_args);
  478.     XtManageChild(box);
  479.     XtRealizeWidget(shell);
  480. !   AddCursor(shell,cursors.top);
  481.   
  482.     num_args = 0;
  483.     shell = XtCreatePopupShell("likeToSave",transientShellWidgetClass,
  484. --- 681,687 ----
  485.                           arglist,num_args);
  486.     XtManageChild(box);
  487.     XtRealizeWidget(shell);
  488. !   AddCursor(shell,resources.cursors.top);
  489.   
  490.     num_args = 0;
  491.     shell = XtCreatePopupShell("likeToSave",transientShellWidgetClass,
  492. ***************
  493. *** 727,731 ****
  494.   
  495.     XtManageChild(box);
  496.     XtRealizeWidget(shell);
  497. !   AddCursor(shell,cursors.top);
  498.   }
  499. --- 739,743 ----
  500.   
  501.     XtManageChild(box);
  502.     XtRealizeWidget(shell);
  503. !   AddCursor(shell,resources.cursors.top);
  504.   }
  505. *** /tmp/,RCSt1a17205    Fri Jan  6 18:56:49 1989
  506. --- clients/xman/man.c    Fri Jan  6 18:42:17 1989
  507. ***************
  508. *** 1,7 ****
  509.   /*
  510.    * xman - X window system manual page display program.
  511.    *
  512. !  * $XConsortium: man.c,v 1.2 88/09/06 17:48:10 jim Exp $
  513.    *
  514.    * Copyright 1987, 1988 Massachusetts Institute of Technology
  515.    *
  516. --- 1,7 ----
  517.   /*
  518.    * xman - X window system manual page display program.
  519.    *
  520. !  * $XConsortium: man.c,v 1.3 89/01/06 18:42:14 kit Exp $
  521.    *
  522.    * Copyright 1987, 1988 Massachusetts Institute of Technology
  523.    *
  524. ***************
  525. *** 20,49 ****
  526.    */
  527.   
  528.   #if ( !defined(lint) && !defined(SABER))
  529. !   static char rcs_version[] = "$Athena: man.c,v 4.0 88/08/31 22:12:33 kit Exp $";
  530.   #endif
  531.   
  532.   #include "globals.h"
  533.   
  534. - static void SetSectionNames();
  535. - static int GetSectNumber();
  536. - static void CheckMandesc();
  537.   static char error_buf[BUFSIZ];        /* The buffer for error messages. */
  538.   
  539. ! /*    Function Name: CmpEntryLabel - used in qsort().
  540. !  *    Description: compares to elements by using their labels.
  541. !  *    Arguments: e1, e2 - two elements to compare by label.
  542. !  *    Returns: an integer >, < or = 0.
  543. !  */
  544.   
  545. ! static int 
  546. ! CmpEntryLabel(e1, e2) 
  547. ! struct entry *e1, *e2;
  548. ! {
  549. !   return(strcmp(e1->label, e2->label));
  550. ! }
  551.   
  552.   /*    Function Name: Man
  553.    *    Description: Builds a list of all manual directories and files.
  554.    *    Arguments: none. 
  555. --- 20,46 ----
  556.    */
  557.   
  558.   #if ( !defined(lint) && !defined(SABER))
  559. !   static char rcs_version[] = "$Athena: man.c,v 4.5 88/12/19 13:47:35 kit Exp $";
  560.   #endif
  561.   
  562.   #include "globals.h"
  563.   
  564.   static char error_buf[BUFSIZ];        /* The buffer for error messages. */
  565.   
  566. ! static void SortList(), ReadMandescFile(), SortAndRemove(), InitManual();
  567. ! static void AddToCurrentSection(), AddNewSection(), AddStandardSections();
  568. ! static int CmpEntryLabel();
  569.   
  570. ! #define SECT_ERROR -1
  571. ! #define streq(a, b)        ( strcmp((a), (b)) == 0 )
  572.   
  573. + typedef struct _SectionList {
  574. +   struct _SectionList * next;    /* link to next elem in list. */
  575. +   char * label, *directory;    /* The label and directory that this 
  576. +                    section represents. */
  577. +   Boolean standard;        /* Is this one of the standard sections? */
  578. + } SectionList;
  579.   /*    Function Name: Man
  580.    *    Description: Builds a list of all manual directories and files.
  581.    *    Arguments: none. 
  582. ***************
  583. *** 53,351 ****
  584.   int
  585.   Man()
  586.   {
  587. !   char *man_nomatch[MAXSECT + 1]; /* allow NULL termination. */
  588. !   char *manptr, manualdir[BUFSIZ], *local_ptr;
  589. !   int i,current[MAXSECT],nsect;
  590.   
  591. !   nsect = FIXEDSECT;
  592.   
  593. !   for (i = 0 ; i < MAXSECT ; i ++) {
  594. !     current[i] = 0;        /* set current entries = 0. */
  595. !     if ( (manual[i].entries = 
  596. !       (struct entry *) malloc(MAXENTRY * sizeof(struct entry))) == NULL )
  597. !       PrintError("Could not allocate memory, while building manpage list.");
  598. !     
  599. !     manual[i].blabel = "Dummy Section Label";
  600. !     manual[i].longest = 1;
  601. !   }
  602.   
  603. !   SetManNames(manual);
  604. !   manptr = getenv("MANPATH");
  605. !   if (manptr == NULL || strcmp(manptr,"") == 0) {
  606. ! #ifdef DEBUG  /* Since man does not complain we had better not either. */
  607. !     sprintf(error_buf,"Could not find MANPATH searching only, %s.",MANDIR);
  608. !     PrintWarning(error_buf);
  609. ! #endif
  610. !     strcpy(manualdir,MANDIR);
  611.     }
  612. !   else
  613. !     strcpy(manualdir,manptr);
  614.   
  615. !   local_ptr = manualdir;
  616. !   do {
  617. !     char *man[MAXSECT];
  618. !     char *curmandir;
  619. !     if ( (manptr = index(local_ptr,':')) != NULL) {    
  620. !       *manptr = '\0';
  621. !       curmandir = local_ptr;
  622. !       local_ptr = manptr + 1;
  623. !     }
  624. !     else
  625. !       curmandir = local_ptr;
  626.   
  627. ! /*    if (!Preformatted(curmandir, manual, current, nsect)) { */
  628. !       if (GetEntry(curmandir,man_nomatch)) {
  629. !     MatchEntries(curmandir,manual,man_nomatch,man,&nsect);
  630. !     AddStruct(manual,curmandir,man,current,nsect);
  631.         }
  632. ! /*    } */
  633.   
  634. !   } while (manptr != NULL);
  635. !   SetSectionNames(manual);
  636. !   SortAndRemove(manual, nsect);
  637. ! #ifdef notdef
  638. !   DumpManual(nsect);
  639.   #endif
  640. !   return(nsect);        /* return the number of man sections. */
  641.   }    
  642.   
  643. ! /*    Function Name: GetEntry
  644. !  *    Description: This function gets the names of the manual page
  645. !  *                   directories, then closes the directory.
  646. !  *    Arguments: path - the path to this directory.
  647. !  *                 man - The directries of unformatted manual pages.
  648. !  *    Returns: FALSE if directory could not be opened.
  649.    */
  650.   
  651. ! static Boolean
  652. ! GetEntry(path, man)
  653. ! char * path;
  654. ! char * man[MAXSECT];
  655.   {
  656. !   DIR * dir;
  657. !   struct stat sb;
  658. !   register struct direct *dp;
  659. !   int numberman;
  660. !   char full_path[BUFSIZ];
  661.   
  662. !   numberman = 0;
  663.   
  664. !   /*
  665. !    * Read through this directory and save up any directory name
  666. !    * which begins with "man".
  667. !    */
  668. !   
  669. !   if((dir = opendir(path)) == NULL) {    
  670. !     sprintf(error_buf,"Can't open directory %s", path);
  671. !     PrintWarning(error_buf);
  672. !     return(FALSE);
  673. !   }
  674.   
  675. !   while((dp = readdir(dir)) != NULL) {
  676. !     if((dp->d_namlen >= LSEARCHDIR) && 
  677. !        (strncmp(dp->d_name, SEARCHDIR, LSEARCHDIR) == 0)) {
  678. !       if(numberman == MAXSECT) 
  679. !     PrintError(
  680. !       "Too many manual sections, recompile with larger allocations");
  681. !       sprintf(full_path, "%s/%s", path, dp->d_name);
  682. !       if((stat(full_path, &sb) >= 0) && (sb.st_mode & S_IFDIR))
  683. !     man[numberman++] = StrAlloc(dp->d_name);
  684.       }
  685.     }
  686. -   
  687. -   man[numberman] = NULL;    /* NULL terminate this list. */
  688. -   closedir(dir);
  689. -   return(TRUE);
  690. - }
  691.   
  692. ! /*    Function Name: MatchEntries
  693. !  *    Description: This fucntion gives the correct number to the 
  694. !  *                   directory, so that all manl entries will be 
  695. !  *                   in the same place.
  696. !  *    Arguments: path - path name if the current searched directory.
  697. !  *                 manual - a pointer to the manual structure.
  698. !  *                 manin - the unmatched states of the directories.
  699. !  *                 manout - the new wonderfully matched directories.
  700. !  *                 number - a pointer to the current number of sections.
  701. !  *    Returns: manout.
  702.    */
  703.   
  704. ! void
  705. ! MatchEntries(path,manual,manin,manout,number)
  706. ! char * path;
  707. ! Manual * manual;
  708. ! char **manin;
  709. ! char **manout;
  710. ! int *number;
  711. ! {
  712. !   int sect;
  713. !   bzero((char *) manout, MAXSECT * sizeof(char *));
  714. !   for ( ; *manin != NULL ; manin++) {
  715. !     if ( (sect = GetSectNumber( (*manin)[LMAN] )) >= 0) 
  716. !       manout[sect] = *manin;
  717.     }
  718.   
  719. !   CheckMandesc(path, manout, manual, number);
  720. ! }
  721. ! /*    Function Name: CheckMandesc
  722.    *    Description: Reads the mandesc file, and adds more sections as 
  723.    *                   nescessary.
  724. !  *    Arguments: path - path name if the current searched directory.
  725. !  *                 manual - a pointer to the manual structure.
  726. !  *                 man - directories, now sorted by order.
  727. !  *                 number - a pointer to the current number of sections.
  728. !  *    Returns: none
  729.    */
  730.     
  731.   static void
  732. ! CheckMandesc(path, manout, manual, number)
  733. ! int *number;
  734.   char * path;
  735. - char ** manout;
  736. - Manual * manual;
  737.   {
  738.     char mandesc_file[BUFSIZ];    /* full path to the mandesc file. */
  739.     FILE * descfile;
  740. !   char character;
  741. !   char string[BUFSIZ];
  742. !   int sectnum;
  743. !   register int j;
  744.   
  745.     sprintf(mandesc_file, "%s/%s", path, MANDESC);
  746. !   if ( (descfile = fopen(mandesc_file, "r")) == NULL) 
  747. !     return;            /* if no description file we are done. */
  748. !   while ( (character = getc(descfile)) != EOF) {
  749. !     Boolean flag = TRUE;
  750.   
  751. !     fgets(string, 100, descfile);
  752. !     string[strlen(string)-1] = '\0';        /* Strip off the CR. */
  753. !     if ( (sectnum = GetSectNumber(character)) >= 0) {
  754. !       if (manout[sectnum] == NULL) {
  755. !     sprintf(error_buf, "Error in file: %s.", mandesc_file);
  756. !     PrintWarning(error_buf);
  757. !     sprintf(error_buf, "Could not find the directory %s/man%c.", 
  758. !         path, character);
  759. !     PrintWarning(error_buf);
  760.       continue;
  761.         }
  762. !       for (j = FIXEDSECT ; j < *number ; j++) {
  763. ! /*
  764. !  * If this section exists then do not create a new one for it.
  765. !  */
  766. !     if ( (!strcmp(manual[j].blabel , string)) ) {
  767. !       manout[j] = manout[sectnum];
  768. !       flag = FALSE;
  769. !     }
  770. !       }
  771. !       if (flag) {
  772. !     manual[*number].blabel = StrAlloc(string);
  773. !     manual[*number].sect = StrAlloc(manout[sectnum]);
  774. !     manout[*number] = StrAlloc(manout[sectnum]);
  775. !     if ( ++(*number) >= MAXSECT) {
  776. !       sprintf(error_buf,"Number of sections exceeded %d recompile %s",
  777. !           MAXSECT,"with larger MAXSECT.");
  778. !         PrintError(error_buf);
  779. !     }
  780. !       } 
  781. !       manout[sectnum][0] = '\0'; /* remove it's name for the prev place */
  782.       }
  783. !     else { /* (sectnum = GetSectNumber(character)) >= 0) */
  784. !       sprintf(error_buf, "Unknown man directory 'man%s'.", character);
  785. !       PrintWarning(error_buf);
  786. !     }
  787.     }
  788. !   fclose(descfile);
  789.   }
  790.   
  791. ! /*    Function Name: AddStruct
  792. !  *    Description: add the new entries to the manual structure.
  793. !  *    Arguments: manual - the manual structure to add them to.
  794. !  *                 path   - the man path for these entires.
  795. !  *                 man  - a pointer to the man directory names. 
  796. !  *                 current - a pointer to the number of the current entry.
  797. !  *    Returns: current - new current pointer numbers and changes manual
  798.    */
  799.   
  800. ! void
  801. ! AddStruct(manual,path,man,current,number)
  802. ! Manual * manual;
  803.   char * path;
  804. - char * man[MAXSECT];
  805. - int current[MAXSECT];
  806. - int number;
  807.   {
  808. !   int i;
  809. !   DIR * dir;
  810. !   register struct direct *dp;
  811. !   char section[BUFSIZ];
  812.   
  813. !   /*
  814. !    * Go through each manual directory saving up the individual
  815. !    * page entries.
  816. !    * Demand that a page entry not start with a '.' but have
  817. !    * a dot somewhere.
  818. !    */
  819.   
  820. !   for(i=0; i < number; i++,man++) {
  821. !     register int j, k;
  822. !     int longest, lpixels;
  823.   
  824. !     longest = lpixels = 1;    /* prevents division by zero. */
  825. !     k = current[i];
  826.   
  827. !     path = StrAlloc(path);    /* allocate a space to save the path. */
  828.   
  829. !     /* 
  830. !      * Use the man directories to get the file names 'cause they should be 
  831. !      * more complete. 
  832. !      */ 
  833.   
  834. !     if (*man == NULL)
  835. !       continue;
  836. !     sprintf(section,"%s/%s",path, *man);
  837. !     if ( (dir = opendir(section)) == NULL) {
  838. !       sprintf(error_buf, "Could not open directory %s.", section);
  839. !       PrintWarning(error_buf);
  840. !       continue;
  841. !     }
  842.   
  843. !     while((dp = readdir(dir)) != NULL) {
  844. !       if( k >= MAXENTRY) {
  845. !     sprintf(error_buf,"Too many manual pages in %s %s", section,
  846. !         "Try recompiling with larger allocations");
  847. !     PrintError(error_buf);
  848. !       }
  849. !       /* starts with a dot? no dot in name? */
  850. !       if( (dp->d_name[0] == '.') || (rindex(dp->d_name,'.') == NULL) )
  851. !     continue;
  852. !       manual[i].entries[k].label = StrAlloc(dp->d_name);
  853. !       manual[i].entries[k].path = path;
  854. !       k++;
  855. ! /* 
  856. !  * This sets the value of the longest string in characters and pixels, I have
  857. !  * to play a few games since the longest string in characters is not 
  858. !  * nescessarily the longest string in pixels, and XTextWidth is not very fast.
  859.    */
  860. !       if ((j = strlen(dp->d_name)) >= longest - 2) {
  861. !     longest = j;
  862. !     if  ( (j = XTextWidth(fonts.directory,dp->d_name,strlen(dp->d_name))) >
  863. !          lpixels)
  864. !     lpixels = j;
  865. !       }
  866.       }
  867. !     closedir(dir);
  868. ! /*
  869. !  * Yes, this check is needed, because we may add to the structure more 
  870. !  * than once, depending on the MANPATH.
  871. !  */
  872. !     if ( (lpixels + 5) > manual[i].longest)
  873. !       manual[i].longest = lpixels+5;
  874. !     current[i] = manual[i].nentries = k;
  875.     }
  876.   }
  877.   
  878.   /*    Function Name: SortAndRemove
  879. --- 50,348 ----
  880.   int
  881.   Man()
  882.   {
  883. !   SectionList *list = NULL;
  884. !   char *ptr, manpath[BUFSIZ], *path, *current_label;
  885. !   int sect;
  886.   
  887. ! /* 
  888. !  * Get the environment variable MANPATH, and if it doesn't exist then back
  889. !  * up to MANDIR.
  890. !  */
  891.   
  892. !   ptr = getenv("MANPATH");
  893. !   if (ptr == NULL || streq(ptr , "") )
  894. !     ptr = MANDIR;
  895. !   strcpy(manpath, ptr);
  896.   
  897. ! /*
  898. !  * Get the list of manual directories in the users MANPATH that we should
  899. !  * open to look for manual pages.  The ``mandesc'' file is read here.
  900. !  */
  901. !   for ( path = manpath ; (ptr = index(path , ':')) != NULL ; path = ++ptr) { 
  902. !     *ptr = '\0';
  903. !     ReadMandescFile(&list, path);
  904.     }
  905. !   ReadMandescFile(&list, path);
  906.   
  907. !   SortList(&list);
  908.   
  909. !   sect = 0;
  910. !   InitManual( &(manual[sect]), list->label );
  911. !   current_label = NULL;
  912. !   while ( list != NULL ) {
  913. !     SectionList * old_list;
  914. !     if ( current_label == NULL || streq(list->label, current_label) )
  915. !       AddToCurrentSection( &(manual[sect]), list->directory);
  916. !     else {
  917. !       if (manual[sect].nentries == 0) {    /* empty section, re-use it. */
  918. !     free(manual[sect].blabel);
  919. !     manual[sect].blabel = list->label;
  920.         }
  921. !       else {
  922. !     if ( ++sect >= MAXSECT ) {
  923. !       sprintf(error_buf, "%s %s", "Too many manual sections, recompile",
  924. !           "with a larger value for MAXSECT.");
  925. !       PrintError(error_buf);
  926. !     }
  927. !     InitManual( &(manual[sect]), list->label );
  928. !       }
  929. !       AddToCurrentSection( &(manual[sect]), list->directory);
  930. !     }
  931. !     /* Save label to see if it matches next entry. */
  932. !     current_label = list->label; 
  933. !     old_list = list;
  934. !     list = list->next;
  935. !     free(old_list);        /* free what you allocate. */
  936. !   }
  937. !   if (manual[sect].nentries != 0)
  938. !     sect++;            /* don't forget that last section. */
  939. !   
  940. !   SortAndRemove(manual, sect);
  941.   
  942. ! #ifdef notdef            /* dump info. */
  943. !   DumpManual(sect);
  944.   #endif
  945. !   return(sect);        /* return the number of man sections. */
  946.   }    
  947.   
  948. ! /*    Function Name: SortList
  949. !  *    Description: Sorts the list of sections to search.
  950. !  *    Arguments: list - a pointer to the list to sort.
  951. !  *    Returns: a sorted list.
  952. !  *
  953. !  * This is the most complicated part of the entire operation.
  954. !  * all sections with the same label must by right next to each other,
  955. !  * but the sections that are in the standard list have to come first.
  956.    */
  957.   
  958. ! static void
  959. ! SortList(list)
  960. ! SectionList ** list;
  961.   {
  962. !   SectionList * local;
  963. !   SectionList *head, *last, *inner, *old;
  964. !   
  965. !   if (*list == NULL)
  966. !     PrintError("No manual sections to read, exiting.");
  967.   
  968. ! /* 
  969. !  * First step 
  970. !  * 
  971. !  * Look for standard list items, and more them to the top of the list.
  972. !  */
  973.   
  974. !   last = NULL;            /* keep Saber happy. */
  975. !   for ( local = *list ; local->next != NULL ; local = local->next) {
  976. !     if ( local->standard ) {
  977. !       if ( local == *list )    /* top element is already standard. */
  978. !     break;
  979. !       head = local;
  980.   
  981. !       /* Find end of standard block */
  982. !       for ( ; (local->next != NULL) && (local->standard) 
  983. !        ; old = local, local = local->next); 
  984. !       last->next = old->next; /* Move the block. */
  985. !       old->next = *list;
  986. !       *list = head;
  987. !       break;            /* First step accomplished. */
  988.       }
  989. +     last = local;
  990.     }
  991.   
  992. ! /*
  993. !  *  Second step
  994. !  *
  995. !  *  Move items with duplicate labels right next to each other.
  996.    */
  997.   
  998. !   local = *list;
  999. !   for ( local = *list ; local->next != NULL ; local = local->next) {
  1000. !     inner = local->next;
  1001. !     while ( inner != NULL) {
  1002. !       if ( streq(inner->label, local->label) && (inner != local->next)) {
  1003. !     last->next = inner->next; /* Move it to directly follow local. */
  1004. !     inner->next = local->next;
  1005. !     local->next = inner;
  1006. !     inner = last;        /* just so that we keep marching down the
  1007. !                    tree (this keeps us from looping). */
  1008. !       }
  1009. !       last = inner;
  1010. !       inner = inner->next;
  1011. !     }
  1012.     }
  1013. + }    
  1014.   
  1015. ! /*    Function Name: ReadMandescFile
  1016.    *    Description: Reads the mandesc file, and adds more sections as 
  1017.    *                   nescessary.
  1018. !  *    Arguments: path - path name if the current search directory.
  1019. !  *                 section_list - pointer to the list of sections.
  1020. !  *    Returns: TRUE in we should use default sections
  1021.    */
  1022.     
  1023.   static void
  1024. ! ReadMandescFile( section_list, path )
  1025. ! SectionList ** section_list;
  1026.   char * path;
  1027.   {
  1028.     char mandesc_file[BUFSIZ];    /* full path to the mandesc file. */
  1029.     FILE * descfile;
  1030. !   char string[BUFSIZ], local_file[BUFSIZ];
  1031. !   Boolean use_defaults = TRUE;
  1032.   
  1033.     sprintf(mandesc_file, "%s/%s", path, MANDESC);
  1034. !   if ( (descfile = fopen(mandesc_file, "r")) != NULL) {
  1035. !     while ( fgets(string, BUFSIZ, descfile) != NULL) {
  1036. !       string[strlen(string)-1] = '\0';        /* Strip off the CR. */
  1037.   
  1038. !       if ( streq(string, NO_SECTION_DEFAULTS) ) {
  1039. !     use_defaults = FALSE;
  1040.       continue;
  1041.         }
  1042. !       sprintf(local_file, "%s%c", MAN, string[0]);
  1043. !       AddNewSection(section_list, path, local_file, (string + 1), FALSE );
  1044.       }
  1045. !     fclose(descfile);
  1046.     }
  1047. !   if (use_defaults)
  1048. !     AddStandardSections(section_list, path);
  1049.   }
  1050.   
  1051. ! /*    Function Name: AddStandardSections
  1052. !  *    Description: Adds all the standard sections to the list for this path.
  1053. !  *    Arguments: list - a pointer to the section list.
  1054. !  *                 path - the path to these standard sections.
  1055. !  *    Returns: none.
  1056.    */
  1057.   
  1058. ! static void
  1059. ! AddStandardSections(list, path)
  1060. ! SectionList **list;
  1061.   char * path;
  1062.   {
  1063. !   static char * names[] = {
  1064. !     "User Commands       (1)",
  1065. !     "System Calls        (2)",
  1066. !     "Subroutines         (3)",
  1067. !     "Devices             (4)",
  1068. !     "File Formats        (5)",
  1069. !     "Games               (6)",
  1070. !     "Miscellaneous       (7)",
  1071. !     "Sys. Administration (8)",
  1072. !     "Local               (l)",
  1073. !     "New                 (n)",
  1074. !     "Old                 (o)",
  1075. !     };
  1076. !   register int i;
  1077. !   char file[BUFSIZ];
  1078.   
  1079. !   for (i = 1 ; i <= 8 ; i++) {
  1080. !     sprintf(file, "%s%d", MAN, i);
  1081. !     AddNewSection(list, path, file, names[i-1], TRUE);
  1082. !   }
  1083. !   i--;
  1084. !   sprintf(file, "%sl", MAN);
  1085. !   AddNewSection(list, path, file, names[i++], TRUE);
  1086. !   sprintf(file, "%sn", MAN);
  1087. !   AddNewSection(list, path, file, names[i++], TRUE);
  1088. !   sprintf(file, "%so", MAN);
  1089. !   AddNewSection(list, path, file, names[i], TRUE);
  1090. ! }
  1091.   
  1092. ! /*    Function Name: AddNewSection
  1093. !  *    Description: Adds the new section onto the current section list.
  1094. !  *    Arguments: list - pointer to the section list.
  1095. !  *                 path - the path to the current manual section.
  1096. !  *                 file - the file to save.
  1097. !  *                 label - the current section label.
  1098. !  *                 standard - one of the standard labels?
  1099. !  *    Returns: none.
  1100. !  */
  1101.   
  1102. ! static void
  1103. ! AddNewSection(list, path, file, label, standard)
  1104. ! SectionList **list;
  1105. ! char * path, * label, * file;
  1106. ! Boolean standard;
  1107. ! {
  1108. !   SectionList * local_list, * end;
  1109. !   char full_path[BUFSIZ];
  1110.   
  1111. ! /* Allocate a new list element */
  1112.   
  1113. !   if ( (local_list = (SectionList *) malloc(sizeof(SectionList)) ) == NULL)
  1114. !     PrintError("Could not allocate Memory in AddNewSection.");
  1115.   
  1116. !   if (*list != NULL) {
  1117. !     for ( end = *list ; end->next != NULL ; end = end->next );
  1118. !     end->next = local_list;
  1119. !   }
  1120. !   else 
  1121. !     *list = local_list;
  1122.   
  1123. !   local_list->next = NULL;
  1124. !   local_list->label = StrAlloc(label);
  1125. !   sprintf(full_path, "%s/%s", path, file);
  1126. !   local_list->directory = StrAlloc(full_path);
  1127. !   local_list->standard = standard;
  1128. ! }  
  1129. ! /*    Function Name: AddToCurrentSection
  1130. !  *    Description: This function gets the names of the manual page
  1131. !  *                   directories, then closes the directory.
  1132. !  *    Arguments:  local_manual - a pointer to a manual pages structure.
  1133. !  *                  path - the path to this directory.
  1134. !  *    Returns: FALSE if directory could not be opened.
  1135.    */
  1136. ! static void
  1137. ! AddToCurrentSection(local_manual, path)
  1138. ! Manual * local_manual;
  1139. ! char * path;
  1140. ! {
  1141. !   DIR * dir;
  1142. !   register struct direct *dp;
  1143. !   register int nentries;
  1144. !   char full_name[BUFSIZ];
  1145. !   if((dir = opendir(path)) == NULL) {    
  1146. ! #ifdef DEBUG
  1147. !     sprintf(error_buf,"Can't open directory %s", path);
  1148. !     PrintWarning(NULL, error_buf);
  1149. ! #endif DEBUG
  1150. !     return;
  1151. !   }
  1152. !   
  1153. !   nentries = local_manual->nentries;
  1154. !   while( (dp = readdir(dir)) != NULL ) {
  1155. !     char * name = dp->d_name;
  1156. !     if( (name[0] == '.') || (index(name, '.') == NULL) ) 
  1157. !       continue;
  1158. !     if ( nentries >= MAXENTRY ) {
  1159. !       sprintf(error_buf, "%s %s %s", "Too many manual pages in directory",
  1160. !           path, "recompile with A larger value for MAXENTRY.");
  1161. !       PrintError(error_buf);
  1162.       }
  1163. !     sprintf(full_name, "%s/%s", path, name);
  1164. !     local_manual->entries[nentries++] = StrAlloc(full_name);
  1165.     }
  1166. +   local_manual->nentries = nentries;
  1167.   }
  1168.   
  1169.   /*    Function Name: SortAndRemove
  1170. ***************
  1171. *** 356,386 ****
  1172.    *    Returns: an improved manual stucure
  1173.    */
  1174.   
  1175. ! void
  1176.   SortAndRemove(manual, number)
  1177.   Manual *manual;
  1178.   int number;
  1179.   {
  1180.     int i;
  1181.   
  1182.     for ( i = 0; i < number; i++) { /* sort each section */
  1183.       register int j = 0;
  1184.       Manual * man = &(manual[i]);
  1185.   
  1186. !     qsort(man->entries, man->nentries, sizeof(struct entry), CmpEntryLabel);
  1187.   
  1188.       while (j < (man->nentries - 1) ) {
  1189. !       if (!strcmp(man->entries[j].label, man->entries[j+1].label)) {
  1190. !     register int k = 0;
  1191. !     for( k = j; k < (man->nentries -1); k++)
  1192. !       man->entries[j] = man->entries[j+1];
  1193.       (man->nentries)--;
  1194.         }
  1195. !       j++;
  1196.       }
  1197.     }
  1198.   }
  1199.   
  1200.   /*    Function Name: StrAlloc
  1201.    *    Description: this function allocates memory for a character string
  1202.    *      pointed to by sp and returns its new pointer.
  1203. --- 353,424 ----
  1204.    *    Returns: an improved manual stucure
  1205.    */
  1206.   
  1207. ! static void
  1208.   SortAndRemove(manual, number)
  1209.   Manual *manual;
  1210.   int number;
  1211.   {
  1212.     int i;
  1213. +   char *l1, *l2;
  1214.   
  1215.     for ( i = 0; i < number; i++) { /* sort each section */
  1216.       register int j = 0;
  1217.       Manual * man = &(manual[i]);
  1218.   
  1219. ! #ifdef DEBUG
  1220. !   printf("sorting section %d - %s\n", i, man->blabel);
  1221. ! #endif DEBUG
  1222.   
  1223. +     qsort(man->entries, man->nentries, sizeof( char * ), CmpEntryLabel);
  1224. + #ifdef DEBUG
  1225. +     printf("removing from section %d.\n", i);
  1226. + #endif DEBUG
  1227. +     if ( (l1 = rindex(man->entries[j], '/')) == NULL)
  1228. +       PrintError("Internal error while removing duplicate manual pages.");
  1229. +     j++;
  1230.       while (j < (man->nentries - 1) ) {
  1231. !       l2 = l1;
  1232. !       if ( (l1 = rindex(man->entries[j], '/')) == NULL)
  1233. !     PrintError("Internal error while removing duplicate manual pages.");
  1234. !       if ( streq(l1, l2) ) {
  1235. !     register int k;
  1236. !     for( k = j; k < (man->nentries); k++)
  1237. !       man->entries[k - 1] = man->entries[k];
  1238.       (man->nentries)--;
  1239.         }
  1240. !       else
  1241. !     j++;
  1242.       }
  1243.     }
  1244.   }
  1245.   
  1246. + /*    Function Name: CmpEntryLabel - used in qsort().
  1247. +  *    Description: compares to elements by using their labels.
  1248. +  *    Arguments: e1, e2 - two items to compare.
  1249. +  *    Returns: an integer >, < or = 0.
  1250. +  */
  1251. + static int 
  1252. + CmpEntryLabel(e1, e2) 
  1253. + char **e1, **e2;
  1254. + {
  1255. +   char *l1, *l2;
  1256. + /*
  1257. +  * What we really want to compare is the actual names of the manual pages,
  1258. +  * and not the full path names.
  1259. +  */
  1260. +   if ( (l1 = rindex(*e1, '/')) == NULL)
  1261. +     PrintError("Internal error while sorting manual pages.");
  1262. +   if ( (l2 = rindex(*e2, '/')) == NULL)
  1263. +     PrintError("Internal error while sorting manual pages.");
  1264. +   return( strcmp(l1, l2) );
  1265. + }
  1266.   /*    Function Name: StrAlloc
  1267.    *    Description: this function allocates memory for a character string
  1268.    *      pointed to by sp and returns its new pointer.
  1269. ***************
  1270. *** 401,493 ****
  1271.     return(ret);
  1272.   }
  1273.   
  1274. ! /*    Function Name:  SetManNames
  1275. !  *    Description: This function give a name to manual.sect
  1276. !  *    Arguments: manual - pointer to the manual structure.
  1277. !  *    Returns: NONE.
  1278. !  */
  1279. ! void
  1280. ! SetManNames(manual)
  1281. ! Manual *manual;
  1282. ! {
  1283. !   int i;
  1284. !   char string[40];
  1285. !   for (i = 0; i < 9; i++) {
  1286. !     sprintf(string,"%s%d",MAN,i);
  1287. !     manual[i].sect = StrAlloc(string);
  1288. !   }
  1289. !   sprintf(string,"%s%c",MAN,'l');
  1290. !   manual[9].sect = StrAlloc(string);
  1291. !   sprintf(string,"%s%c",MAN,'n');
  1292. !   manual[10].sect = StrAlloc(string);
  1293. ! }
  1294. ! /*    Function Name: GetSectNumber
  1295. !  *    Description: this gets a section number of a fixed section.
  1296. !  *    Arguments: character - the character representing the section.
  1297. !  *    Returns: the number of that section.
  1298. !  */
  1299. ! static int
  1300. ! GetSectNumber(c)
  1301. ! char c;
  1302. ! {
  1303. !   switch (c) {
  1304. !   case '0':
  1305. !   case '1':
  1306. !   case '2':
  1307. !   case '3':
  1308. !   case '4':
  1309. !   case '5':
  1310. !   case '6':
  1311. !   case '7':
  1312. !   case '8':
  1313. !     return(c - '0');
  1314. !   case 'l':
  1315. !     return(9);
  1316. !   case 'n':
  1317. !     return(10);
  1318. !   default:
  1319. !     break;            /* ignore others, and return -1. */
  1320. !   }
  1321. !   return(-1);
  1322. ! }
  1323. ! /*    Function Name: SetSectNames
  1324. !  *    Description: Sets the section names.
  1325. !  *    Arguments: manual - the manual structure.
  1326.    *    Returns: none.
  1327.    */
  1328.   
  1329.   static void
  1330. ! SetSectionNames(manual)
  1331. ! Manual * manual;
  1332.   {
  1333. !   /* These are the names for the first 10 sections. */
  1334. !   static char * names[] = {
  1335. !     "foo bar (0)",
  1336. !     "User Commands (1)",
  1337. !     "System Calls (2)",
  1338. !     "Subroutines(3)",
  1339. !     "Devices (4)",
  1340. !     "File Formats (5)",
  1341. !     "Games (6)",
  1342. !     "Miscellaneous (7)",
  1343. !     "Sys. Administration (8)",
  1344. !     "Local (l)",
  1345. !     "New (n)"
  1346. !     };
  1347. !   register int i;
  1348. !   for (i = 1; i < FIXEDSECT; i++)
  1349. !     manual[i].blabel = names[i];
  1350.   }
  1351.   #if defined(DEBUG)
  1352.   
  1353.   /*    Function Name: DumpManual
  1354. --- 439,463 ----
  1355.     return(ret);
  1356.   }
  1357.   
  1358. ! /*    Function Name: InitManual
  1359. !  *    Description: Initializes this manual section.
  1360. !  *    Arguments: l_manual - local copy of the manual structure.
  1361. !  *                 label - the button label for this section.
  1362.    *    Returns: none.
  1363.    */
  1364.   
  1365.   static void
  1366. ! InitManual(l_manual, label)
  1367. ! Manual * l_manual;
  1368. ! char * label;
  1369.   {
  1370. !   bzero( l_manual, sizeof(Manual) );            /* clear it. */
  1371. !   l_manual->blabel = label;                    /* set label. */
  1372. !   l_manual->entries = (char **) malloc( sizeof(char *) * MAXENTRY);
  1373. !   if (l_manual->entries == NULL)
  1374. !     PrintError("Could not allocate memory in InitManual().");
  1375.   }
  1376. !   
  1377.   #if defined(DEBUG)
  1378.   
  1379.   /*    Function Name: DumpManual
  1380. ***************
  1381. *** 502,510 ****
  1382.     register int i,j;
  1383.     
  1384.     for ( i = 0; i < number; i++) {
  1385.       for (j = 0; j < manual[i].nentries; j++) 
  1386. !       printf("path %-10s label %-20s\n", manual[i].entries[j].path,
  1387. !          manual[i].entries[j].label);
  1388.     }
  1389.   }
  1390.   
  1391. --- 472,480 ----
  1392.     register int i,j;
  1393.     
  1394.     for ( i = 0; i < number; i++) {
  1395. +     printf("label: %s\n", manual[i].blabel);
  1396.       for (j = 0; j < manual[i].nentries; j++) 
  1397. !       printf("%s\n", manual[i].entries[j]);
  1398.     }
  1399.   }
  1400.   
  1401. *** /tmp/,RCSt1a17235    Fri Jan  6 18:56:59 1989
  1402. --- clients/xman/misc.c    Fri Jan  6 18:42:26 1989
  1403. ***************
  1404. *** 1,7 ****
  1405.   /*
  1406.    * xman - X window system manual page display program.
  1407.    *
  1408. !  * $XConsortium: misc.c,v 1.3 88/10/07 17:19:53 jim Exp $
  1409.    *
  1410.    * Copyright 1987, 1988 Massachusetts Institute of Technology
  1411.    *
  1412. --- 1,7 ----
  1413.   /*
  1414.    * xman - X window system manual page display program.
  1415.    *
  1416. !  * $XConsortium: misc.c,v 1.4 89/01/06 18:42:24 kit Exp $
  1417.    *
  1418.    * Copyright 1987, 1988 Massachusetts Institute of Technology
  1419.    *
  1420. ***************
  1421. *** 20,26 ****
  1422.    */
  1423.   
  1424.   #if ( !defined(lint) && !defined(SABER))
  1425. !   static char rcs_version[] = "$Athena: misc.c,v 4.0 88/08/31 22:13:01 kit Exp $";
  1426.   #endif
  1427.   
  1428.   #include "globals.h"
  1429. --- 20,26 ----
  1430.    */
  1431.   
  1432.   #if ( !defined(lint) && !defined(SABER))
  1433. !   static char rcs_version[] = "$Athena: misc.c,v 4.6 88/12/19 13:48:01 kit Exp $";
  1434.   #endif
  1435.   
  1436.   #include "globals.h"
  1437. ***************
  1438. *** 37,46 ****
  1439.    */
  1440.   
  1441.   void
  1442. ! PrintWarning(string)
  1443.   char * string;
  1444.   {
  1445. !   fprintf(stderr,"Xman Warning: %s\n",string);
  1446.   }
  1447.   
  1448.   /*    Function Name: PrintError
  1449. --- 37,54 ----
  1450.    */
  1451.   
  1452.   void
  1453. ! PrintWarning(man_globals, string)
  1454. ! ManpageGlobals * man_globals;
  1455.   char * string;
  1456.   {
  1457. !   char buffer[BUFSIZ];
  1458. !   sprintf( buffer, "Xman Warning: %s", string);
  1459. !   if (man_globals != NULL) 
  1460. !     ChangeLabel(man_globals->label, buffer);
  1461. !   fprintf(stderr, "%s\n", buffer);
  1462.   }
  1463.   
  1464.   /*    Function Name: PrintError
  1465. ***************
  1466. *** 63,88 ****
  1467.   /*    Function Name: FindFilename
  1468.    *    Description: Opens the entry file given the entry struct.
  1469.    *    Arguments: man_globals - the globals info for this manpage.
  1470. -  *                 name - name of the current manpage.
  1471.    *                 entry - the structure containg the info on the file to open.
  1472.    *    Returns: fp - the file pointer
  1473.    */
  1474.   
  1475.   FILE *
  1476. ! FindFilename(man_globals, name, section, entry)
  1477.   ManpageGlobals * man_globals;
  1478. ! char * name;
  1479. ! int section;
  1480. ! struct entry * entry;
  1481.   {
  1482.     FILE * file;
  1483. !   char local_filename[BUFSIZ];    /* local filename. */
  1484.   
  1485. !   sprintf(man_globals->manpage_title,
  1486. !       "The current manual page is: %s.", name);   
  1487.     
  1488. !   sprintf(man_globals->filename, "%s/%s%c/%s",
  1489. !       entry->path, CAT,  manual[section].sect[LCAT], entry->label);
  1490.   
  1491.   /* if we find the formatted manpage then return it */
  1492.   
  1493. --- 71,94 ----
  1494.   /*    Function Name: FindFilename
  1495.    *    Description: Opens the entry file given the entry struct.
  1496.    *    Arguments: man_globals - the globals info for this manpage.
  1497.    *                 entry - the structure containg the info on the file to open.
  1498.    *    Returns: fp - the file pointer
  1499.    */
  1500.   
  1501.   FILE *
  1502. ! FindFilename(man_globals, entry)
  1503.   ManpageGlobals * man_globals;
  1504. ! char * entry;
  1505.   {
  1506.     FILE * file;
  1507. !   char path[BUFSIZ], page[BUFSIZ], section[BUFSIZ], *temp;
  1508.   
  1509. !   temp = CreateManpageName(entry);
  1510. !   sprintf(man_globals->manpage_title, "The current manual page is: %s.", temp);
  1511. !   free(temp);
  1512.     
  1513. !   ParseEntry(entry, path, section, page);
  1514. !   sprintf(man_globals->filename, "%s/%s%c/%s", path, CAT, section[LCAT], page);
  1515.   
  1516.   /* if we find the formatted manpage then return it */
  1517.   
  1518. ***************
  1519. *** 89,109 ****
  1520.     if ( (file = fopen(man_globals->filename,"r")) != NULL)
  1521.       return(file);
  1522.   
  1523. ! /* If not then look for the unformatted man page, format it and 
  1524. !  * write access is allowed to the cat directory, then ask if we
  1525. !  * want to save it.
  1526. !  */
  1527. !   sprintf(local_filename,"%s/%s/%s",
  1528. !       entry->path, manual[section].sect, entry->label);
  1529. !   if ( (file = fopen(local_filename,"r")) == NULL) {
  1530. !     char error_buf[BUFSIZ];
  1531. !     /* We Really could not find it, this should never happen, yea right. */
  1532. !     sprintf(error_buf, "Could open manual page file, %s", local_filename);
  1533. !     PrintError(error_buf);
  1534. !   }
  1535. !   else 
  1536. !     return(Format(man_globals,file,local_filename, entry, section));
  1537.   }
  1538.   
  1539.   /*    Function Name: Format
  1540. --- 95,101 ----
  1541.     if ( (file = fopen(man_globals->filename,"r")) != NULL)
  1542.       return(file);
  1543.   
  1544. !   return(Format(man_globals, entry));
  1545.   }
  1546.   
  1547.   /*    Function Name: Format
  1548. ***************
  1549. *** 111,118 ****
  1550.    *                   with the user.
  1551.    *    Arguments: man_globals - the psuedo globals
  1552.    *                 file - the file pointer to use and return
  1553. -  *                 local_filename - the name of the file that is 
  1554. -  *                                  being formatted.
  1555.    *                 entry - the current entry struct.
  1556.    *                 current_box - The current directory being displayed. 
  1557.    *    Returns: none.
  1558. --- 103,108 ----
  1559. ***************
  1560. *** 121,138 ****
  1561.   /* ARGSUSED */
  1562.   
  1563.   FILE *
  1564. ! Format(man_globals, file, local_filename, entry, current_box)
  1565.   ManpageGlobals * man_globals; 
  1566. ! FILE * file;
  1567. ! char * local_filename;
  1568. ! struct entry * entry;
  1569. ! int current_box;        /* The current directory being displayed.  */
  1570.   {
  1571.     Widget w = man_globals->manpagewidgets.directory;
  1572. !   char cmdbuf[256];
  1573. !   char tmp[25];
  1574. !   char catdir[100];
  1575. !   int x,y;            /* location to pop up whould you 
  1576.                      like to save widget. */
  1577.   
  1578.     strcpy(tmp,MANTEMP);        /* get a temp file. */
  1579. --- 111,126 ----
  1580.   /* ARGSUSED */
  1581.   
  1582.   FILE *
  1583. ! Format(man_globals, entry)
  1584.   ManpageGlobals * man_globals; 
  1585. ! char * entry;
  1586.   {
  1587. +   FILE * file;
  1588.     Widget w = man_globals->manpagewidgets.directory;
  1589. !   char cmdbuf[BUFSIZ], tmp[BUFSIZ], catdir[BUFSIZ];
  1590. !   char path[BUFSIZ], section[BUFSIZ], error_buf[BUFSIZ];
  1591. !   Position x,y;            /* location to pop up whould you 
  1592.                      like to save widget. */
  1593.   
  1594.     strcpy(tmp,MANTEMP);        /* get a temp file. */
  1595. ***************
  1596. *** 157,187 ****
  1597.     XFlush(XtDisplay(w));
  1598.   */
  1599.   /* End replacement. */
  1600. ! /*
  1601. !   ChangeLabel(man_globals->label, "Formatting Manpage, Please Stand by...");
  1602. ! */
  1603.   #ifdef macII
  1604. !   sprintf(cmdbuf,"cd %s;/usr/bin/pcat %s | /usr/bin/col | /usr/bin/ul -t dumb > %s",
  1605. !       entry->path, local_filename, man_globals->tmpfile);
  1606.   #else
  1607. !   sprintf(cmdbuf,"cd %s;%s %s > %s",
  1608. !       entry->path,
  1609. !       FORMAT, local_filename, man_globals->tmpfile);
  1610.   #endif
  1611.   
  1612. !   if(system(cmdbuf) != 0)     /* execute search. */
  1613. !     PrintError("Something went wrong trying to run the command");
  1614.   
  1615.     if ((file = fopen(man_globals->tmpfile,"r")) == NULL) {  
  1616. !     PrintWarning("Something went wrong in retrieving the temp file");
  1617. !     PrintError("Try cleaning up /tmp");
  1618.     }
  1619.   
  1620.   /* if the catdir is writeable the ask the user if he/she wants to
  1621.      write the man page to it. */
  1622.   
  1623. !   sprintf(catdir,"%s/%s%c",
  1624. !       entry->path,CAT, manual[current_box].sect[LCAT], entry->label);
  1625.     
  1626.     if( (access(catdir,W_OK)) == 0)  {
  1627.       x = Width(man_globals->manpagewidgets.manpage)/2;
  1628. --- 145,187 ----
  1629.     XFlush(XtDisplay(w));
  1630.   */
  1631.   /* End replacement. */
  1632. !   if ( (file = fopen( entry , "r")) == NULL) {
  1633. !     /* We Really could not find it, this should never happen, yea right. */
  1634. !     sprintf(error_buf, "Could open manual page file, %s", entry);
  1635. !     PrintWarning(man_globals, error_buf);
  1636. !     return(NULL);
  1637. !   }
  1638. !   ParseEntry(entry, path, section, NULL);
  1639.   #ifdef macII
  1640. !   sprintf(cmdbuf,
  1641. !         "cd %s;/usr/bin/pcat %s | /usr/bin/col | /usr/bin/ul -t dumb > %s %s",
  1642. !     path, entry, man_globals->tmpfile, "2> /dev/null");
  1643.   #else
  1644. !   sprintf(cmdbuf,"cd %s ; %s %s > %s %s", path,
  1645. !       FORMAT, entry, man_globals->tmpfile, "2> /dev/null");
  1646.   #endif
  1647.   
  1648. !   if(system(cmdbuf) != 0) {    /* execute search. */
  1649. !     sprintf(error_buf,
  1650. !         "Something went wrong trying to run the command: %s", cmdbuf);
  1651. !     PrintWarning(man_globals, error_buf);
  1652. !     return(NULL);
  1653. !   }
  1654.   
  1655.     if ((file = fopen(man_globals->tmpfile,"r")) == NULL) {  
  1656. !     sprintf(error_buf, "Something went wrong in retrieving the temp file, %s",
  1657. !         "Try cleaning up /tmp");
  1658. !     PrintWarning(man_globals, error_buf);
  1659. !     return(NULL);
  1660.     }
  1661.   
  1662.   /* if the catdir is writeable the ask the user if he/she wants to
  1663.      write the man page to it. */
  1664.   
  1665. !   sprintf(catdir,"%s/%s%c", path, CAT, section[LCAT]);
  1666.     
  1667.     if( (access(catdir,W_OK)) == 0)  {
  1668.       x = Width(man_globals->manpagewidgets.manpage)/2;
  1669. ***************
  1670. *** 188,194 ****
  1671.       y = Height(man_globals->manpagewidgets.manpage)/2;
  1672.       XtTranslateCoords(man_globals->manpagewidgets.manpage, x, y, &x, &y);
  1673.       PositionCenter( PopupChild(man_globals->manpagewidgets.manpage, 0),
  1674. !            x,y,0,0,0,0);
  1675.       XtPopup( PopupChild(man_globals->manpagewidgets.manpage, 0),
  1676.           XtGrabExclusive);
  1677.     }
  1678. --- 188,194 ----
  1679.       y = Height(man_globals->manpagewidgets.manpage)/2;
  1680.       XtTranslateCoords(man_globals->manpagewidgets.manpage, x, y, &x, &y);
  1681.       PositionCenter( PopupChild(man_globals->manpagewidgets.manpage, 0),
  1682. !            (int) x, (int) y,0,0,0,0);
  1683.       XtPopup( PopupChild(man_globals->manpagewidgets.manpage, 0),
  1684.           XtGrabExclusive);
  1685.     }
  1686. ***************
  1687. *** 232,238 ****
  1688.   {
  1689.   
  1690.     if (!XtIsRealized(w)) {
  1691. !     PrintWarning("Widget is not realized, no cursor added.\n");
  1692.       return;
  1693.     }
  1694.     XDefineCursor(XtDisplay(w),XtWindow(w),cursor);
  1695. --- 232,238 ----
  1696.   {
  1697.   
  1698.     if (!XtIsRealized(w)) {
  1699. !     PrintWarning(NULL, "Widget is not realized, no cursor added.\n");
  1700.       return;
  1701.     }
  1702.     XDefineCursor(XtDisplay(w),XtWindow(w),cursor);
  1703. ***************
  1704. *** 316,318 ****
  1705. --- 316,352 ----
  1706.     XtMoveWidget(widget,x_temp,y_temp);
  1707.   }  
  1708.   
  1709. + /*    Function Name: ParseEntry(entry, path, sect, page)
  1710. +  *    Description: Parses the manual pages entry filenames.
  1711. +  *    Arguments: str - the full path name.
  1712. +  *                 path - the path name.      RETURNED
  1713. +  *                 sect - the section name.   RETURNED
  1714. +  *                 page - the page name.      RETURNED
  1715. +  *    Returns: none.
  1716. +  */
  1717. + void
  1718. + ParseEntry(entry, path, sect, page)
  1719. + char *entry, *path, *page, *sect;
  1720. + {
  1721. +   char *c, temp[BUFSIZ];
  1722. +   strcpy(temp, entry);
  1723. +   c = rindex(temp, '/');
  1724. +   if (c == NULL) 
  1725. +     PrintError("index failure in ParseEntry.");
  1726. +   *c++ = '\0';
  1727. +   if (page != NULL)
  1728. +     strcpy(page, c);
  1729. +   c = rindex(temp, '/');
  1730. +   if (c == NULL) 
  1731. +     PrintError("index failure in ParseEntry.");
  1732. +   *c++ = '\0';
  1733. +   if (sect != NULL)
  1734. +     strcpy(sect, c);
  1735. +   if (path != NULL)
  1736. +     strcpy(path, temp);
  1737. + }
  1738. -- 
  1739. Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
  1740. Moderator of comp.sources.x
  1741.